package com.blog.service.Impl;
import com.blog.Utils.AliOssUtil;
import com.blog.Utils.CookieUtils;
import com.blog.Utils.MailClient;
import com.blog.base.Constans;
import com.blog.bean.domain.User;
import com.blog.bean.dto.PassDTO;
import com.blog.bean.dto.UserDTO;
import com.blog.exception.ServiceException;
import com.blog.mapper.UserMapper;
import com.blog.service.UserService;
import com.blog.bean.vo.LoginVo;
import com.blog.bean.vo.UserErrorVO;
import com.blog.bean.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @author 任浩
 * @version 1.0
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private SpringTemplateEngine templateEngine;
    @Autowired
    private MailClient mailClient;
    @Autowired
    private AliOssUtil aliOssUtil;
    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 对用户注册的密码等信息进行检验。
     * 0代表加入成功 1该账号已存在! 2密码长度不能小于8位!  3 两次输入的密码不一致 4 该邮箱已注册
     *
     * @param userDTO
     * @return
     */
    @Override
    @Transactional
    public UserErrorVO check(UserDTO userDTO) {

        UserErrorVO userErrorVO = new UserErrorVO();
        //检验账户是否存在。
        List<User> list = new ArrayList<>();
        list = userMapper.checkUserName(userDTO.getUsername());

        if (list.size() > 0) {
            userErrorVO.setCode(1);
            return userErrorVO;
        }

        //检验密码长度是否小于8位
        if (userDTO.getPassword().length() < 8) {
            userErrorVO.setCode(2);
            return userErrorVO;
        }

        //检验两次输入的密码是否一致
        String pass = userDTO.getPassword();
        String repass = userDTO.getRepassword();
        if (!(pass.equals(repass))) {
            userErrorVO.setCode(3);
            return userErrorVO;
        }

        //检验邮箱是否被注册
//        list = userMapper.checkEmail(userDTO.getEmail());
//
//        if(list != null){
//            userErrorVO.setCode(4);
//            return userErrorVO;
//        }

        User registerUser = new User();
        //经过检验，把这些数据保存到数据库中。返回注册成功。
        BeanUtils.copyProperties(userDTO, registerUser);

        log.info("user信息为:" + registerUser);

        //设置用户的状态为：未激活
        registerUser.setStatus(0);
        //设置用户创建时间
        registerUser.setCreateTime(LocalDateTime.now());
        //设置salt
        registerUser.setSalt("hello");
        //设置用户类型
        registerUser.setType(0);

        //设置头像，给的是默认头像。
        //可以后面更改头像
        registerUser.setHeaderUrl("http://static.nowcoder.com/images/head/notify.png");

        //然后进行添加新用户
        userMapper.add(registerUser);

        userErrorVO.setCode(0);

        //激活邮件
        Context context = new Context();

        //设置邮件跳转的路径
        //激活的路径为: http://localhost:8081/user/active/id  //根据用户的id号码，来设置激活状态。
        String url = "http://localhost:8081/user/active/" + registerUser.getId();
        context.setVariable("url", url);

        String send = templateEngine.process("send", context);
        mailClient.sendMsg(registerUser.getEmail(), "激活账户", send);

        log.info("需要激活用户的id为：" + registerUser.getId());

        return userErrorVO;
    }

    /**
     * 激活用户
     * @param id
     */
    @Override 
    public void update(int id) {
        User user = new User();
        user.setId(id);
        user.setStatus(1);
        userMapper.update(user);
    }

    /**
     * 登录用户
     * @param user
     * @return
     */
    @Override
    public UserErrorVO login(LoginVo user, String vaild){

        UserErrorVO userErrorVO = new UserErrorVO();

        //验证账户是否存在.
        List<User> list = userMapper.checkUserName(user.getUsername());

        // 用户不存在
        if(list.size() == 0 ){
            userErrorVO.setCode(1);
            return userErrorVO;
        }

        //密码长度不能低于8位
        if(user.getPassword().length() < 8 ){
            userErrorVO.setCode(2);
            return userErrorVO;
        }

        //验证验证码是否正确。
        if(!(user.getVaild().equals(vaild))){
            userErrorVO.setCode(3);
            return userErrorVO;
        }

        User user1 = new User();
        BeanUtils.copyProperties(user,user1);
        User us = userMapper.check(user1);

        if(us == null){
            userErrorVO.setCode(4);
            return userErrorVO;
        }
        //如果登录成功，返回0，代表成功
        userErrorVO.setCode(0);
        userErrorVO.setUserId(us.getId()); //设置用户id
        userErrorVO.setUserStatus(1); //设置用户的状态。
        userErrorVO.setUsername(us.getUsername()); //设置用户名
        userErrorVO.setHeaderUrl(us.getHeaderUrl());

        return userErrorVO;
    }

    /**
     * 得到用户详细信息
     * @return
     */
    @Override
    public UserVO getDetailMessage(Integer userId) {
        User user = new User();
        user.setId(userId);

        //得到查询到的用户信息
        User userDetail = userMapper.check(user);
        UserVO userVO = new UserVO();
        userVO.setCreateTime(userDetail.getCreateTime());
        userVO.setHeaderUrl(userDetail.getHeaderUrl());
        userVO.setUsername(userDetail.getUsername());
        userVO.setId(userDetail.getId());

        return userVO;
    }

    /**
     * 上传头像
     * @param image
     * @return
     */
    @Override
    public UserVO upload(MultipartFile image,Integer userid) throws IOException {
        User user = new User();
        UserVO userVO = new UserVO();
        String randString = UUID.randomUUID().toString();//得到随机的一个字符。
        randString += ".png";
        String upload = aliOssUtil.upload(image.getBytes(), randString);
        //把当前图片路径保存到用户中。
        user.setId(userid);
        user.setHeaderUrl(upload); //设置图片路径
        userMapper.update(user);

        userVO.setHeaderUrl(upload);
        return userVO;
    }

    /**
     * 获取当前用户信息
     * @param request
     * @param response
     * @return
     */
    @Override
    public User getCurrentUser(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> cookieMessage = CookieUtils.getCookieMessage(request);

        String token = cookieMessage.get(Constans.Cookie_Token);
        String userId = cookieMessage.get(Constans.Cookie_User);
        if(userId == null || token == null){
            log.info("当前用户没有登录，不能获取到用户信息");
            throw new ServiceException(302,"不能获取到用户信息");
        }

//        cookieMessage.forEach((k,v)->{
//            if(Constans.Cookie_User.equals(k)){
//                String userId = v;
//                //比较传过来的token和我们存放在缓存里的token是否是一致的。
//                String tmpToken = redisTemplate.opsForValue().get(userId);
//
//                if(!tmpToken.equals(token)){
//                    log.info("当前用户没有登录，不能获取到用户信息");
//                    throw new ServiceException(302,"不能获取到用户信息");
//                }
//            }
//        });

        //比较传过来的token和我们存放在缓存里的token是否是一致的。
        String tmpToken = redisTemplate.opsForValue().get(userId);

        if(!tmpToken.equals(token)){
            log.info("token已过期，不能获取到用户信息");
            throw new ServiceException(302,"token已过期，不能获取到用户信息");
        }

        User user = userMapper.selectById(userId);
        log.info("查询出来的用户信息为：" + user);
        return user;
    }

    /**
     * 修改用户密码
     * @param passDTO
     * @param userid
     * @return
     */
    @Override
    public UserErrorVO updatePass(PassDTO passDTO, Integer userid) {
        UserErrorVO userErrorVO = new UserErrorVO();
        User user = new User();
        user.setId(userid);

        //判断原密码是否超过8位。
        if(passDTO.getOriginpass().length() < 8){
            userErrorVO.setCode(1);
            return userErrorVO;
        }

        //判断新密码是否超过8位
        if(passDTO.getNewpass().length() < 8){
            userErrorVO.setCode(2);
            return userErrorVO;
        }

        //判断新密码输入两次是否一样
        String newpass = passDTO.getNewpass();
        String ackpass = passDTO.getAckpass();
        if(!newpass.equals(ackpass)){
            userErrorVO.setCode(3);
            return userErrorVO;
        }

        //判断当前用户的原密码是否输入正确。
        String originpass = passDTO.getOriginpass();
        User check = userMapper.check(user);
        if(!originpass.equals(check.getPassword())){
            userErrorVO.setCode(4);
            return userErrorVO;
        }

        //把当前用户密码进行更新，更新为新密码。
        user.setPassword(originpass);
        userMapper.check(user);

        //设置更改成功
        userErrorVO.setCode(0);

        return userErrorVO;
    }
}

